package com.github.wxiaoqi.security.auth.common.util.jwt;

import org.joda.time.DateTime;

import com.github.wxiaoqi.security.auth.common.bean.JWTInfo;
import com.github.wxiaoqi.security.auth.common.constatns.CommonConstants;
import com.github.wxiaoqi.security.auth.common.util.StringHelper;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

/**
 * Created by ace on 2017/9/10.
 */
public class JWTHelper {
	private static RsaKeyHelper rsaKeyHelper = new RsaKeyHelper();

	/**
	 * 密钥加密token
	 *
	 * @param jwtInfo
	 * @param priKeyPath
	 * @param expire
	 * @return
	 * @throws Exception
	 */
	public static String generateToken(IJWTInfo jwtInfo, String priKeyPath, int expire) throws Exception {
		String compactJws = Jwts.builder().setSubject(jwtInfo.getUniqueName())
				.claim(CommonConstants.JWT_KEY_PLATFORMID, jwtInfo.getPlatformId())// 在token中加入平台编号
				.claim(CommonConstants.JWT_KEY_NAME, jwtInfo.getName()) // token中包含用户名称或是微服务客户端名称
				.claim(CommonConstants.JWT_KEY_X_ID, jwtInfo.getXId())
				.claim(CommonConstants.JWT_KEY_SALTKEY, jwtInfo.getSaltKey())// 验证签名用的盐值
				.setExpiration(DateTime.now().plusSeconds(expire).toDate())
				.signWith(SignatureAlgorithm.RS256, rsaKeyHelper.getPrivateKey(priKeyPath)).compact();
		return compactJws;
	}

	/**
	 * 密钥加密token
	 *
	 * @param jwtInfo
	 * @param priKey
	 * @param expire
	 * @return
	 * @throws Exception
	 */
	public static String generateToken(IJWTInfo jwtInfo, byte priKey[], int expire) throws Exception {
		String compactJws = Jwts.builder().setSubject(jwtInfo.getUniqueName())
				.claim(CommonConstants.JWT_KEY_PLATFORMID, jwtInfo.getPlatformId())// 在token中加入平台编号
				.claim(CommonConstants.JWT_KEY_NAME, jwtInfo.getName()) // token中包含用户名称或是微服务客户端名称
				.claim(CommonConstants.JWT_KEY_X_ID, jwtInfo.getXId())
				.claim(CommonConstants.JWT_KEY_SALTKEY, jwtInfo.getSaltKey())// 验证签名用的盐值
				.setExpiration(DateTime.now().plusSeconds(expire).toDate())
				.signWith(SignatureAlgorithm.RS256, rsaKeyHelper.getPrivateKey(priKey)).compact();
		return compactJws;
	}
	

	/**
	 * 公钥解析token
	 *
	 * @param token
	 * @return
	 * @throws Exception
	 */
	public static Jws<Claims> parserToken(String token, String pubKeyPath) throws Exception {
		Jws<Claims> claimsJws = Jwts.parser().setSigningKey(rsaKeyHelper.getPublicKey(pubKeyPath))
				.parseClaimsJws(token);
		return claimsJws;
	}

	/**
	 * 公钥解析token
	 *
	 * @param token
	 * @return
	 * @throws Exception
	 */
	public static Jws<Claims> parserToken(String token, byte[] pubKey) throws Exception {
		Jws<Claims> claimsJws = Jwts.parser().setSigningKey(rsaKeyHelper.getPublicKey(pubKey)).parseClaimsJws(token);
		return claimsJws;
	}

	/**
	 * 获取token中的用户信息
	 *
	 * @param token
	 * @param pubKeyPath
	 * @return
	 * @throws Exception
	 */
	public static IJWTInfo getInfoFromToken(String token, String pubKeyPath) throws Exception {
		Jws<Claims> claimsJws = parserToken(token, pubKeyPath);
		Claims body = claimsJws.getBody();
		return new JWTInfo(StringHelper.getObjectValue(body.get(CommonConstants.JWT_KEY_PLATFORMID)), StringHelper.getObjectValue(body.get(CommonConstants.JWT_KEY_NAME)),
				StringHelper.getObjectValue(body.get(CommonConstants.JWT_KEY_X_ID)));
	}

	/**
	 * 获取token中的用户信息
	 * @param token
	 * @param pubKey
	 * @return
	 * @throws Exception
	 */
	public static IJWTInfo getInfoFromToken(String token, byte[] pubKey) throws Exception {
		Jws<Claims> claimsJws = parserToken(token, pubKey);
		Claims body = claimsJws.getBody();
		if (null != body.get(CommonConstants.JWT_KEY_PLATFORMID) && null != body.get(CommonConstants.JWT_KEY_SALTKEY)) {
			return new JWTInfo(StringHelper.getObjectValue(body.get(CommonConstants.JWT_KEY_PLATFORMID)),
					StringHelper.getObjectValue(body.get(CommonConstants.JWT_KEY_SALTKEY)),StringHelper.getObjectValue(body.get(CommonConstants.JWT_KEY_SALTKEY)));
		}
		return new JWTInfo(StringHelper.getObjectValue(body.get(CommonConstants.JWT_KEY_PLATFORMID)), StringHelper.getObjectValue(body.get(CommonConstants.JWT_KEY_NAME)),
				StringHelper.getObjectValue(body.get(CommonConstants.JWT_KEY_X_ID)));
	}
}
